import redis
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
# Create your views here.
from users.models import Users
from goods.models import Goods


# 添加购物车
class AddCart(APIView):
    def post(self, request):
        # 获取前端传来的数据
        user_name = request.data.get("user")
        pid = request.data.get("productID")
        # 获取用户对象
        try:
            user = Users.objects.get(username=user_name)
        except Exception as e:
            print(e)
            return Response({'msg': '用户不存在', 'code': 400})
        # 获取商品对象
        try:
            good = Goods.objects.get(id=pid)
        except Exception as e:
            print(e)
            return Response({'msg': '此商品不存在', 'code': 400})
        # 链接redis
        rdb = redis.Redis()
        # 构建hash的key
        cart_key = 'cart_%s' % user.id  # hash中的key
        cart_selected = 'cart_selected_%s' % user.id  # 集合中的key
        # 默认的商品数量
        count = 1
        # 判断商品的存库
        if good.stock > 0:
            # 有存库的判断条件
            # 判断商品在redis中是否存在
            num = rdb.hget(cart_key, pid)
            # 存在就累加
            if num:
                # 购物车中商品的总数量是否大于存库
                # 获取购物车中此商品的总数量,但是从redis中取出的数据是byte类型要转码,然后转换数据类型
                good_count = int(num.decode())
                good_count += count
                # 购物车的总数量和商品的存库做对比, 不大于就加购
                if good_count <= good.stock:
                    rdb.hset(cart_key, pid, good_count)
                    rdb.sadd(cart_selected, pid)
                    # 关闭redis
                    rdb.close()
                    return Response({'msg': '改商品已经在购物车， 数量+1', 'code': 200})
                else:
                    # 超出存库，不添加
                    # 关闭redis
                    rdb.close()
                    return Response({'msg': '加购达到限购数量！', 'code': 400})
            # 不存在就新加
            else:
                rdb.hset(cart_key, pid, count)  # 写入hash
                rdb.sadd(cart_selected, pid)
                shopping_cart_data = {
                    "id": cart_key,
                    "productID": pid,
                    "productName": good.sku_name,
                    "productImg": good.img,
                    "price": good.selling_price,
                    "num": count,  # 该商品在购物车中的数量
                    "maxNum": good.stock,  # 限购数量
                    "check": True,  # 加购，默认是勾选状态
                }
                # 关闭redis
                rdb.close()
                return Response({"code": 200, "msg": "新加入购物车成功！", "shoppingCartData": shopping_cart_data})
        else:
            return Response({'msg': '存库不足', 'code': 400})


# 查看购物车
class GetCart(APIView):
    def post(self, request):
        try:
            # 获取前端数据
            user_name = request.data.get("user").get("userName")
            # 查询当前用户
            try:
                user = Users.objects.get(username=user_name)
            except Exception as e:
                print(e)
                return Response({'msg': '用户不存在', 'code': 400})
            cart_key = "cart_%s" % user.id
            cart_selected_key = "cart_selected_%s" % user.id
            # 链接redis
            rdb = redis.Redis(host='127.0.0.1', port=6379)
            shopping_cart_data = []
            # 购物车中勾选的商品
            cart_selected = [int(i.decode()) for i in rdb.smembers(cart_selected_key)]
            # 遍历每个商品
            for good_id, g_count in rdb.hgetall(cart_key).items():
                good_id = int(good_id.decode())
                g_count = int(g_count.decode())
                # 整理一个商品字典数据
                if good_id in cart_selected:  # 商品被勾选
                    one_good = get_one_good(cart_key, good_id, g_count, check=True)
                else:
                    one_good = get_one_good(cart_key, good_id, g_count, check=False)
                # 将当前商品字典追加到列表中
                shopping_cart_data.append(one_good)
            return Response({"code": 200, 'msg': "获取用户的购物车数据成功！", "shoppingCartData": shopping_cart_data})
        except Exception as e:
            print(e)
            return Response({'msg': '服务器获取购物车数据异常', 'code': 400})


# 把购物车里的每一个商品，组织成一个字典
def get_one_good(cart_key, good_id, g_count, check=False):
    try:
        good = Goods.objects.get(id=good_id)
    except Exception as e:
        print(e)
        return {}
    return {
        "id": cart_key,
        "productID": good_id,
        "productName": good.sku_name,
        "productImg": good.img,
        "price": good.selling_price,
        "num": g_count,  # 该商品 在当前购物车中的数量
        "maxNum": good.stock,  # 限购数量
        "check": check,  # 购物车中该商品是否被勾选
    }


# 更新购物车商品数量
class UpDataCartNum(APIView):
    def post(self, request):
        # 获取前端数据
        user_name = request.data.get("user")
        pid = request.data.get("productID")
        good_num = request.data.get("num")
        # 用户判断
        try:
            user = Users.objects.get(username=user_name['userName'])
        except Exception as e:
            print(e)
            return Response({'msg': '用户不存在', 'code': 400})
        # 根据用户信息构建key
        cart_key = "cart_%s" % user.id
        cart_selected = "cart_selected_%s" % user.id
        # 链接redis
        rdb = redis.Redis()
        # 更新商品数量
        # 被更新的商品的状态设为勾选
        try:
            rdb.sadd(cart_selected, pid)
            # 更新数量
            rdb.hset(cart_key, pid, good_num)
            rdb.close()
        except Exception as e:
            print(e)
            return Response({'msg': '更新商品数量失败', 'code': 400})
        return Response({'msg': '更新商品数量成功', 'code': 200})

    # 更新购物车商品状态
    def get(self, request):
        # 获取查询字符串的参数
        pid = request.query_params.get("productID")
        # hash 中的key
        cart_key = request.query_params.get("cartID")
        # 购物车的id
        status = request.query_params.get("val")
        # 修改集合中的商品状态
        # 要修改的是集合中的商品状态, key 是cart_selected_uid  v 是 pid
        # 通过购物车id,获取uid 从而获取cart_selected_uid
        print('cart_Key----->', cart_key)
        # 把购物车中cart_key中的用户id,获取
        cart_selected = "cart_selected_%s" % cart_key.split("_")[-1]
        # 链接redis
        rdb = redis.Redis()
        # 修改状态，接受的是修改后的状态
        if status == 'true':
            rdb.sadd(cart_selected, pid)
        else:
            rdb.srem(cart_selected, pid)
        rdb.close()
        return Response({'msg': '修改状态成功', 'code': 200})

    # 修改全选
    def put(self, request):
        cart_key = request.data.get("cartID")
        status = request.data.get("val")
        # 获取购物车中cart_key中的id
        cart_selected = "cart_selected_%s" % cart_key.split("_")[-1]
        # 链接redis
        rdb = redis.Redis()
        # 若status 是true, 说明之前没有勾选, 要加到set
        if status == 'true':
            # 获取所有的商品id
            goods = rdb.hkeys(cart_key)
            rdb.sadd(cart_selected, *goods)
        # 若status 是false, 说明之前勾选,要从set中删除
        else:
            rdb.delete(cart_selected)  # 删除redis中的key
        return Response({'msg': '修改状态成功', 'code': 200})
